/**
 * licenses
 * 
 */

package com.openjawtech.xscraper.flights.dao.impl;

import com.openjawtech.xscraper.flights.dao.FlightDAO;
import com.openjawtech.xscraper.flights.domain.Airport;
import com.openjawtech.xscraper.flights.domain.Flight;
import java.util.Date;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>implement all flight dao methods
 *
 * <p>16/02/2009
 * @author Wenbo.Sun
 */
public class FlightDAOImpl extends BaseDAO implements FlightDAO {

    private static final Log log = LogFactory.getLog(FlightDAOImpl.class);
    @Override
    public void delete(Flight flight) {
        log.debug("deleting the flight instance -- id: " + flight.getFlightId());
        try {
            getSession().delete(flight);
            log.debug("flight instance has been deleted!");
        } catch (RuntimeException re) {
            log.error("delete flight instance failed -- id: " + flight.getFlightId(), re);
            throw re;
        }
    }

    @Override
    public Flight getByTravel(Airport departure, Airport arrival, Date travelDate) {
        log.debug("retrieving flight -- departure id: " + departure.getAirportId() + " -- "
                + "arrival id: " + arrival.getAirportId());
        try{
            String query = "from Flight flight where flight.airportByArrivalId = ? and "
                    + "flight.airportByDepartureId = ? and flight.travelDate = ?";
            Flight flight = (Flight) getSession().createQuery(query).setParameter(0, arrival).setParameter(1, departure)
                    .setParameter(2, travelDate).iterate().next();
            log.debug("flight instance has been retrieved!");
            return flight;
        } catch (RuntimeException re){
            log.error("retrieve flight failed", re);
            throw re;
        }
    }

    @Override
    public List<Flight> getByTravels(Airport departure, Airport arrival, Date start, Date end) {
        log.debug("retrieving flights -- departure id: " + departure.getAirportId() + " -- "
                + "arrival id: " + arrival.getAirportId());
        try{
            String query = "from Flight flight where flight.airportByArrivalId = ? and "
                    + "flight.airportByDepartureId = ? and flight.travelDate >= ?"
                    + "and flight.travelDate <= ?";
            List<Flight> flights = getSession().createQuery(query).setParameter(0, arrival).setParameter(1, departure)
                    .setParameter(2, start).setParameter(3, end).list();
            log.debug("flights have been retrieved");
            return flights;
        } catch (RuntimeException re){
            log.error("retrieve flights failed!");
            throw re;
        }
    }

    @Override
    public boolean isExisted(Airport departure, Airport arrival, Date travelDate) {
        log.debug("check existence of flight -- departure id: " + departure.getAirportId() + " -- "
                + "arrival id: " + arrival.getAirportId());
        try{
            String query = "from Flight flight where flight.airportByArrivalId = ? and "
                    + "flight.airportByDepartureId = ? and flight.travelDate = ?";
            boolean result = getSession().createQuery(query).setParameter(0, arrival).setParameter(1, departure)
                    .setParameter(2, travelDate).iterate().hasNext();
            log.debug("flight instance has been checked!");
            return result;
        } catch (RuntimeException re){
            log.error("check flight failed", re);
            throw re;
        }
    }

    @Override
    public boolean isExisted(Airport departure, Airport arrival) {
        log.debug("check existence of flight -- departure id: " + departure.getAirportId() + " -- "
                + "arrival id: " + arrival.getAirportId());
        try{
            String query = "from Flight flight where flight.airportByArrivalId = ? and "
                    + "flight.airportByDepartureId = ?";
            boolean result = getSession().createQuery(query).setParameter(0, arrival).setParameter(1, departure)
                    .iterate().hasNext();
            log.debug("flight instance has been checked!");
            return result;
        } catch (RuntimeException re){
            log.error("check flight failed", re);
            throw re;
        }
    }

    @Override
    public void save(Flight flight) {
        log.debug("saving flight -- departure id: " + flight.getAirportByDepartureId().getAirportId() + " -- "
                + "arrival id: " + flight.getAirportByArrivalId().getAirportId());
        try {
            getSession().save(flight);
            log.debug("flight instance has been saved!");
        } catch (RuntimeException re) {
            log.error("save flight instance failed ", re);
            throw re;
        }
    }

    @Override
    public void update(Flight flight) {
        log.debug("updating the flight instance -- id: " + flight.getFlightId());
        try {
            getSession().update(flight);
            log.debug("flight instance has been updated!");
        } catch (RuntimeException re) {
            log.error("update flight instance failed -- id: " + flight.getFlightId(), re);
            throw re;
        }
    }

}
